/**
 * @file:   main.c
 * @note:   2010-2020, <git.oschia.net/think3r>
 * @brief   
 * @author: think3r
 * @date    2018/7/2
 * @note:
 * @note \n History:
   1.日    期: 2018/7/2
     作    者: think3r
     修改历史: 创建文件
 */

/*----------------------------------------------*/
/*                  头文件包含                  */
/*----------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>  /* 使用 exit() 函数 */
#include <string.h>
#include <unistd.h>

#include "common.h"
#include "build_time.h"
#include "yuvConvert.h"

/*----------------------------------------------*/
/*                  宏类型定义                  */
/*----------------------------------------------*/
#if defined(_WIN32) || defined(WIN32)  
#endif

/*----------------------------------------------*/
/*                 结构体定义                   */
/*----------------------------------------------*/

/*----------------------------------------------*/
/*                  函数声明                    */
/*----------------------------------------------*/

/*----------------------------------------------*/
/*                  全局变量                    */
/*----------------------------------------------*/

char helpInfo[] = 
        "[usage]:\n"
        "\t[-f]   \tSet file path of yuvFile\n"
        "\t[-i]   \tSet file  width & height as WxH\n"        
        "\t[-s]   \tSet srcFormate\n"
        "\t[-d]   \tSet distFormate\n"
        "\t[-h]   \tPrint help Info\n"        
        "\t[-v]   \tPrint version\n"
        "\n"
        "[Formate]:\n"
        "    [YUV-420]:\n"
        "        I420/YU12:       [YYYYYYYY] [UU] [VV] \n"
        "        YV12:            [YYYYYYYY] [VV] [UU] \n"
        "        NV12:            [YYYYYYYY] [UVUV]    \n"
        "        NV21:            [YYYYYYYY] [VUVU]    \n"
        "    [YUV-422]:\n"
        "        YUV422P:         [YYYY] [UU] [VV]     \n"
        "        YUV422SP:        [YYYY] [UVUV]        \n"
        "        UYVY/Y422/UYNV:  [UYVY UYVY]          \n"
        "        YUYV/YUY2/YUNV:  [YUYV YUYV]          \n";


static char SOFT_VERSION[] = "yuvConvert v0.1";

/* YUV 文件存放路径         */
char srcFilePath[100] = {0};   
char distFilePath[100] = "./outPut.yuv";
long srcFileSize = -1, srcFrameSize = -1;;
int frameWidth = -1, frameHeight = -1;
YUV_FORMATE srcFormate = YUV_ERR_TYPE;
YUV_FORMATE distFormate = YUV_ERR_TYPE;

/*----------------------------------------------*/
/*                  函数定义                    */
/*----------------------------------------------*/
   
/**
 * @function:   decodeArgV
 * @brief:      解析传递进来的命令行参数
 * @param[in]:  int argc      
 * @param[in]:  char *argv[]  
 * @param[out]: None
 * @return:     
 */
ERR decodeArgV(int argc, char *argv[])
{    
    int opt = 0;  
    char deCodeFromate[] = "hvf:i:s:d:";    
	extern char * optarg;
    char * wxh = NULL;
    char srcFormateChar[100] = {0}, distFormateChar[100] = {0};

#if 0    //打印输入参数
    UINT i = 0;

    printf("argc:%d\r\n", argc);    

    for ( i = 0 ; i < argc ; i++ )
    {
        printf("argv%d:[%s]\n", i, argv[i]);
    }
#endif   /* end of (#if 0  //打印输入参数) */

    if(argc == 1)
    {
        printf("\n%s\n",helpInfo);  
        exit(0);
    }
    
    while((opt = getopt(argc, argv, deCodeFromate)) != -1)
    {  
         switch(opt)
         {
            case 'h':  
                printf("\n%s\n",helpInfo);  
                exit(0);
            case 'v':
                printf("\n%s\n",SOFT_VERSION);  
                exit(0);
            case 'f':
                if ( strlen(optarg) > sizeof(srcFilePath))
                {
                    printf(" your input Parameter [dataBase path] is too long!!\n");                      
                    exit(1);
                }
                else
                {                    
                    strcpy(srcFilePath, optarg);
                    if(GetFileSize(srcFilePath, &srcFileSize) != OK)
                    {
                        printf("file not exits!\n");                       
                        exit(1);
                    }
                    else
                    {
                        printf("srcFile: [%s] Size:[%ld B], [%ld KB], [%0.2lf MB]\n", 
                            srcFilePath, srcFileSize, srcFileSize/1024, 
                            (float)srcFileSize/1024/1024);
                    }
                }
                break;            
            case 'i':
                wxh = optarg;                
                frameWidth = strtol(wxh, &wxh, 0);
                wxh ++;/*略去中间的分隔字符;*/
                frameHeight = strtol(wxh, &wxh, 0);
                printf("WxH: [%d x %d]\n", frameWidth, frameHeight);
                break;
            case 's':
                strcpy(srcFormateChar, optarg);
                if(decodeInputFromate(srcFormateChar, &srcFormate) != OK)
                {
                    printf("ERR!!! your input Formate:[%s] not support\n", optarg);
                    exit(1);
                }
                Cprintf_green("[%s %d]  srcFormate:[0x%02x]\n",__FUNCTION__,__LINE__,srcFormate);
                break;
            case 'd':
                strcpy(distFormateChar, optarg);
                if(decodeInputFromate(distFormateChar, &distFormate) != OK)
                {
                    printf("ERR!!! your input Formate:[%s] not support\n", optarg);
                    exit(1);
                }
                Cprintf_green("[%s %d]  distFormate:[0x%02x]\n",__FUNCTION__,__LINE__,distFormate);
                break;            
            default:  
                printf("Undefine Command!!\n");                  
                exit(1);
         }  
    }  

    return ok;
}

/**
 * @function:   checkGlobalParam
 * @brief:      校验必须的全局变量
 * @param[in]:  void  
 * @param[out]: None
 * @return:     ERR
 */
ERR checkGlobalParam(void)
{        
    
    if(strlen(srcFilePath) == 0)
    {
        printf(" ERR!!!!  [src-file-Path]  should be Input!!\n");
        exit(1);
    }

    if(frameWidth == -1 || frameHeight == -1)
    {
        printf("ERR!!!! Must input [W&H!]\n");
        exit(1);
    }

    if(srcFormate == YUV_ERR_TYPE || distFormate == YUV_ERR_TYPE)
    {
        printf("ERR!!! Must input [Src&Dist-Formate]!\n");
        exit(1);
    }

    if(srcFormate & YUV_420_FORMATE)
    {
        srcFrameSize = 1.5 * frameWidth * frameHeight;
    }
    else if(srcFormate & YUV_422_FORMATE)
    {        
        srcFrameSize = 2 * frameWidth * frameHeight;
    }
    else if(srcFormate & YUV_444_FORMATE)
    {
        srcFrameSize = 3 * frameWidth * frameHeight;
    }
    else
    {
        printf("[%s %d]  ERR  [Src-Formate!!]\n",__FUNCTION__,__LINE__);        
        exit(1);
    }

    /*文件大小, 跟与 输入宽高,格式计算出来的大小, 对应不上.*/
    if( (srcFrameSize == 0) || (srcFileSize % srcFrameSize != 0))
    {
        printf("ERR Size;   SrcFileSize:[%ld] SrcFrameSize:[%ld], reminder:[%ld]\n",
                      srcFileSize, srcFrameSize, srcFileSize % srcFrameSize );
        exit(1);
    }

    return ok;
}

/*
  实例用法:
    ./yuvConvert -f ./p420_1920x1080_10_0_yuv444.yuv  -s I420 -d NV12 -i 1920*1080
*/

int main(int argc, char ** argv)
{
    mk_Build_Date(NULL);

    decodeArgV(argc, argv);

    checkGlobalParam();   

    Cprintf_red("[%s %d]  hello world~ Success!!\n",__FUNCTION__,__LINE__);

    return 1;
}

